﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Settings = RaytheonTimeWindows.Properties.Settings;
using RaytheonTimeDataModel;


namespace RaytheonTimeWindows
{
    public partial class frmMain : Form
    {
        #region Private Data Members

        BindingList<Workday> workdayBindingList_;

        #endregion

        #region Constructor

        public frmMain()
        {
            InitializeComponent();
        }

        #endregion

        #region Overriden Event Handlers

        protected override void OnLoad(EventArgs e)
        {
            try
            {
                base.OnLoad(e);

                dgvWorkdays.ColumnHeadersBorderStyle = (SystemFonts.MessageBoxFont.Name == "Segoe UI") ?
                                                        DataGridViewHeaderBorderStyle.None :
                                                        DataGridViewHeaderBorderStyle.Raised;
                LoadWorkDays();
            }
            catch (Exception ex)
            {
                String message = "Error occurred Loading frmMain\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        protected override void OnShown(EventArgs e)
        {
            try
            {
                base.OnShown(e);

                if (Settings.Default.WindowIsMax)
                {
                    this.WindowState = FormWindowState.Maximized;
                }
                else
                {
                    this.WindowState = FormWindowState.Normal;
                    this.Location = Settings.Default.WindowLocation;
                    this.Size = Settings.Default.WindowSize;
                }
            }
            catch (Exception ex)
            {
                String message = "Error occurred Showing frmMain\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            try
            {
                base.OnClosing(e);

                if (this.WindowState == FormWindowState.Normal)
                {
                    Settings.Default.WindowIsMax = false;
                    Settings.Default.WindowLocation = this.Location;
                    Settings.Default.WindowSize = this.Size;
                }
                else
                {
                    Settings.Default.WindowIsMax = true;
                }
                Settings.Default.Save();
            }
            catch (Exception ex)
            {
                String message = "Error occurred Closing Application\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region Private Event Handlers

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.KeyCode == Keys.Escape)
                {
                    this.Close();
                }
            }
            catch (Exception ex)
            {
                String message = "Error occurred Pressing the Escape Key\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Application.Exit();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Quit\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                frmEditWorkday form = new frmEditWorkday();
                form.DataChangedCallback = new Common.DataChangedDelegate(this.UpdateDataCallback);
                form.Show();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking New\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                RefreshDataGrid();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Refresh\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void editToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                EditWorkDay();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Edit\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Delete();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Delete\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                AboutRayTime form = new AboutRayTime();
                form.Show();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking About\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void summaryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Summary();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Summary\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dgvWorkdays_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                EditWorkDay();
            }
            catch (Exception ex)
            {
                String message = "Error occurred double clicking the workdays grid\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void summaryToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                Summary();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Summary - 1\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void editToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                EditWorkDay();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Edit - 1\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                Delete();
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking Delete - 1\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dgvWorkdays_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.KeyCode == Keys.Delete)
                {
                    Delete();
                }
            }
            catch (Exception ex)
            {
                String message = "Error occurred pressing the Delete key\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dgvWorkdays_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    var hti = dgvWorkdays.HitTest(e.X, e.Y);
                    dgvWorkdays.ClearSelection();
                    dgvWorkdays.Rows[hti.RowIndex].Selected = true;
                }
            }
            catch (Exception ex)
            {
                String message = "Error occurred clicking mouse button on the workday grid\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region Private Methods

        private void LoadWorkDays()
        {
            using (var db = new RaytheonTimeDataEntities())
            {
                bool colorSwitch = true;
                bool isNewWeek = false;
                DateTime prevDate = DateTime.Now;
                DateTime currDate = DateTime.Now;
                bool didPrintWorkweek = false;
                int rowIndex = -1;
                int startOfWeekIndex = -1;

                double weeklyTotalRegTime = 0.0;
                double weeklyTotalOt = 0.0;
                double weeklyTotalPto = 0.0;
                double weeklTotalOther = 0.0;
                double weeklyTotalTime = 0.0;

                var workdays = (from b in db.Workdays
                                where b.isDeleted == false
                                orderby b.workdayDate descending
                                select b);

                workdayBindingList_ = new BindingList<Workday>(workdays.ToList());
                dgvWorkdays.DataSource = workdayBindingList_;
                
                rowIndex = 0;
                foreach (var workday in workdays)
                {
                    currDate = workday.workdayDate;
                    didPrintWorkweek = false;

                    if (rowIndex > 0)
                    {
                        isNewWeek = Common.IsNewWeek(currDate, prevDate);
                    }
                    else
                    {
                        startOfWeekIndex = rowIndex;
                    }

                    if (isNewWeek)
                    {
                        colorSwitch = !colorSwitch; // switch colors

                        dgvWorkdays.Rows[startOfWeekIndex].Cells[4].Value = weeklyTotalRegTime;
                        dgvWorkdays.Rows[startOfWeekIndex].Cells[5].Value = weeklyTotalOt;
                        dgvWorkdays.Rows[startOfWeekIndex].Cells[6].Value = weeklyTotalPto;
                        dgvWorkdays.Rows[startOfWeekIndex].Cells[7].Value = weeklTotalOther;
                        dgvWorkdays.Rows[startOfWeekIndex].Cells[8].Value = weeklyTotalTime;
                        
                        weeklyTotalRegTime = 0.0;
                        weeklyTotalOt = 0.0;
                        weeklyTotalPto = 0.0; 
                        weeklTotalOther = 0.0;
                        weeklyTotalTime = 0.0;

                        didPrintWorkweek = true;
                        startOfWeekIndex = rowIndex;
                    }

                    if (colorSwitch)
                    {
                        dgvWorkdays.Rows[rowIndex].DefaultCellStyle.BackColor = Color.MediumSeaGreen;
                    }
                    else
                    {
                        dgvWorkdays.Rows[rowIndex].DefaultCellStyle.BackColor = Color.SeaGreen;
                    }

                    foreach (var worktime in workday.Worktimes)
                    {
                        if (worktime.ChargeNumberAttribute.attributeText.Trim() == 
                                ChargeNumberAttribute.ChargeTypeStrings[(int)ChargeNumberAttribute.ChargeType.StraightTime])
                        {
                            weeklyTotalRegTime += worktime.duration;
                        }
                        else if (worktime.ChargeNumberAttribute.attributeText.Trim() ==
                                    ChargeNumberAttribute.ChargeTypeStrings[(int)ChargeNumberAttribute.ChargeType.OverTime])
                        {
                            weeklyTotalOt += worktime.duration;
                        }
                        else if (worktime.ChargeNumberAttribute.attributeText.Trim() ==
                                    ChargeNumberAttribute.ChargeTypeStrings[(int)ChargeNumberAttribute.ChargeType.PTO_Exempt] ||
                                 worktime.ChargeNumberAttribute.attributeText.Trim() ==
                                    ChargeNumberAttribute.ChargeTypeStrings[(int)ChargeNumberAttribute.ChargeType.PTO])
                        {
                            weeklyTotalPto += worktime.duration;
                        }
                        else
                        {
                            weeklTotalOther += worktime.duration;
                        }
                    }

                    weeklyTotalTime += workday.hours;

                    prevDate = currDate;

                    isNewWeek = false;
                    ++rowIndex;
                }

                if (!didPrintWorkweek && rowIndex > -1)
                {
                    dgvWorkdays.Rows[startOfWeekIndex].Cells[4].Value = weeklyTotalRegTime;
                    dgvWorkdays.Rows[startOfWeekIndex].Cells[5].Value = weeklyTotalOt;
                    dgvWorkdays.Rows[startOfWeekIndex].Cells[6].Value = weeklyTotalPto;
                    dgvWorkdays.Rows[startOfWeekIndex].Cells[7].Value = weeklTotalOther;
                    dgvWorkdays.Rows[startOfWeekIndex].Cells[8].Value = weeklyTotalTime;
                }

                dgvWorkdays.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
                // TODO: Eventually probably should figure out sorting
                //dgvWorkdays.Sort(date, ListSortDirection.Ascending);
            }
        }

        private void EditWorkDay()
        {
            if (dgvWorkdays.SelectedRows.Count == 1)
            {
                try
                {
                    Int32 workdayId = Convert.ToInt32(dgvWorkdays.SelectedRows[0].Cells[0].Value);
                    frmEditWorkday form = new frmEditWorkday(workdayId);
                    form.DataChangedCallback = new Common.DataChangedDelegate(this.UpdateDataCallback);
                    form.Show();
                }
                catch (Exception ex)
                {
                    String message = "Error occurred Editing Worktime\n";
                    message += ex.Message;
                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("You must select a row before clicking Edit", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void Summary()
        {
            if (dgvWorkdays.SelectedRows.Count == 1)
            {
                try
                {
                    Int32 workdayId = Convert.ToInt32(dgvWorkdays.SelectedRows[0].Cells[0].Value);
                    Common.DisplaySummary(workdayId);
                }
                catch (Exception ex)
                {
                    String message = "Error occurred clicking on Summary\n";
                    message += ex.Message;
                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("You must select a row before clicking Summary", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void RefreshDataGrid()
        {
            try
            {
                dgvWorkdays.Rows.Clear();
                LoadWorkDays();
            }
            catch (Exception ex)
            {
                String message = "Error occurred refreshing workdays\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void Delete()
        {
            if (dgvWorkdays.SelectedRows.Count == 1)
            {
                try
                {
                    DialogResult dr = MessageBox.Show("Are you sure you and to delete the selected row?", "Delete Confirmation",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (dr == System.Windows.Forms.DialogResult.Yes)
                    {
                        Int32 workdayId = Convert.ToInt32(dgvWorkdays.SelectedRows[0].Cells[0].Value);
                        using (var db = new RaytheonTimeDataEntities())
                        {
                            var workday = (from b in db.Workdays
                                           where b.workdayId == workdayId
                                           select b).FirstOrDefault();
                            workday.isDeleted = true;

                            db.SaveChanges();
                        }

                        dgvWorkdays.Rows.Clear();
                        LoadWorkDays();
                    }
                }
                catch (Exception ex)
                {
                    String message = "Error occurred Deleting Workday\n";
                    message += ex.Message;
                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("You must select a row before clicking Delete", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void UpdateDataCallback()
        {
            try
            {
                RefreshDataGrid();
            }
            catch (Exception ex)
            {
                String message = "Error occurred Updating Data Callback (refresh)\n";
                message += ex.Message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion
    }
}
